
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       SoftSerial.h
  * @author     baiyang
  * @date       2022-6-11
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
#include <stdbool.h>
/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/
enum serial_config {
    SERIAL_CONFIG_8N1  = 0, // DSM, SRXL etc, 8 bit, no parity, 1 stop bit
    SERIAL_CONFIG_8E2I = 1, // SBUS, 8 bit, even parity, 2 stop bits, inverted
    SERIAL_CONFIG_8N1I = 2, // FPort inverted, 8 bit, no parity, 1 stop bit
};

typedef struct soft_serial* soft_serial_t;

struct soft_serial {
    uint32_t baudrate;
    uint8_t half_bit; // width of half a bit in microseconds
    enum serial_config config;

    uint8_t data_width;
    uint8_t byte_width;
    uint16_t stop_mask;
    uint32_t timestamp_us;
    uint32_t byte_timestamp_us;

    struct {
        uint32_t byte;
        uint16_t bit_ofs;
    } state;

};

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
void softserial_ctor(soft_serial_t softserial, uint32_t _baudrate, enum serial_config _config);
bool softserial_process_pulse(soft_serial_t softserial, uint32_t width_high, uint32_t width_low, uint8_t *byte);

// get timestamp of the last byte
static inline uint32_t softserial_get_byte_timestamp_us(soft_serial_t softserial) { return softserial->byte_timestamp_us; }
static inline uint32_t softserial_baud(soft_serial_t softserial) { return softserial->baudrate; }
/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



